package com.dongzili.sp_mongodb.service;

import com.dongzili.sp_mongodb.controller.BaseController;
import com.dongzili.sp_mongodb.dao.UserRepository;
import com.dongzili.sp_mongodb.model.User;
import com.mongodb.client.result.UpdateResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

@Service
public class UserService{
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private MongoTemplate mongoTemplate;

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public Optional<User> getUserById(String id) {
        return userRepository.findById(id);
    }

    public User createUser(User user) {
        return userRepository.save(user);
    }

    public Optional<User> updateUser(String id, User user) {
        if (userRepository.existsById(id)) {
//            User existingUser = userRepository.findOne(query, User.class);
//            user.setId(id); // 设置要更新的文档的 ID


            Query query = new Query(Criteria.where("_id").is(id));
            Update update = new Update();

            // 检查entity对象中所有字段，如果不为空则更新
            Field[] fields = user.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                try {
                    Object value = field.get(user);
                    if (value != null) {
                        update.set(field.getName(), value);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            UpdateResult result = mongoTemplate.updateFirst(query, update, User.class);
            System.out.println(result);
            return userRepository.findById(id);
        }
        return null;
    }

    public void deleteUser(String id) {
        userRepository.deleteById(id);
    }


    public List<User> findPageUserAll(Integer pageNum, Integer pageSize, User user){
        //设置分页参数
        //0代表第一页
        Pageable pageable = PageRequest.of(pageNum, pageSize);

        Example<User> userExample = Example.of(user);//查询条件
        Page<User> page = userRepository.findAll(userExample, pageable);
        return page.getContent();
    }

    public List<User> dynamicQuery(Map<String, Object> query) {

        Criteria criteria = new Criteria();
        query.forEach((key, value) -> {
            if (value instanceof Map) {
                Map<String,Object> mapValue = (Map<String,Object>) value;
                for (Map.Entry<String, Object> entry : mapValue.entrySet()) {
                    switch (entry.getKey()) {
                        case "eq": // 等于
                            criteria.and(key).is(entry.getValue());
                            break;
                        case "ne": // 不等于
                            criteria.and(key).ne(entry.getValue());
                            break;
                        case "gt": // 大于
                            criteria.and(key).gt(entry.getValue());
                            break;
                        case "gte": // 大于等于
                            criteria.and(key).gte(entry.getValue());
                            break;
                        case "lt": // 小于
                            criteria.and(key).lt(entry.getValue());
                            break;
                        case "lte": // 小于等于
                            criteria.and(key).lte(entry.getValue());
                            break;
                        case "in": // 在指定数组内
                            criteria.and(key).in((List) entry.getValue());
                            break;
                        case "nin": // 不在指定数组内
                            criteria.and(key).nin((List) entry.getValue());
                            break;
                        case "exists": // 字段是否存在
                            criteria.and(key).exists((Boolean) entry.getValue());
                            break;
                        case "regex": // 正则表达式匹配
                            criteria.and(key).regex(Pattern.compile(entry.getValue().toString()));
                            break;
                        case "like": // 模糊查询，这里简化处理为正则表达式匹配
                            criteria.and(key).regex(Pattern.compile(entry.getValue().toString(), Pattern.CASE_INSENSITIVE));
                            break;
                        case "between": // 在两个值之间
                            List<Object> betweenValues = (List<Object>) entry.getValue();
                            if(betweenValues.size() == 2) {
                                criteria.and(key).gte(betweenValues.get(0)).lte(betweenValues.get(1));
                            }
                            break;
                        case "all": // 匹配数组中所有值
                            criteria.and(key).all((List) entry.getValue());
                            break;
                        case "size": // 数组大小
                            criteria.and(key).size((Integer) entry.getValue());
                            break;
                        case "elemMatch": // 匹配数组中至少有一个元素满足指定条件
                            if(entry.getValue() instanceof Map) {
                                Criteria elemMatchCriteria = new Criteria();
                                ((Map<?,?>) entry.getValue()).forEach((k, v) -> elemMatchCriteria.and(k.toString()).is(v));
                                criteria.and(key).elemMatch(elemMatchCriteria);
                            }
                            break;
                        // 追加更多的比较方式...
                        default:
                            // 可以添加日志或异常处理，说明未处理的条件
                            break;
                    }
                }
            }
        });

        Query dynamicQuery = new Query(criteria);
        List<User> results = mongoTemplate.find(dynamicQuery, User.class);
        return results;
    }
}